package ioTest;

import io.IO;

import junit.framework.*;
import org.junit.Test;
import org.junit.After;
import org.junit.Before;




import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;




public class IOTest extends TestCase 
{

	private IO io;
	

	private String receivedInput;
	private String[] actualOutput;
	private String actualInput;
	
	
	private ByteArrayOutputStream out;
	private InputStream in;
	public IOTest(String name)
	{
		super(name);
	}

	@Before
	public void setUp() throws Exception 
	{
		
	}

	@After
	public void tearDown() throws Exception 
	{
	}
	
	private void setInOutStream(){	
		// set a test output
		out = new ByteArrayOutputStream();
        System.setOut(new PrintStream(out));
     
 
        // set a test input
		in = new ByteArrayInputStream(actualInput.getBytes());
		System.setIn(in);
	
	}
	
	private void getScreenResult() throws IOException
	{
		

       
        
		// get the actual screen output
        out.flush();  
        String whatWasPrinted = new String(out.toByteArray());
        actualOutput = whatWasPrinted.split(System.getProperty("line.separator"));  
        
     
 	   
		
	}

		
		
	




	@Test
	public void testGetReportingRoomNumber_404() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Reporting Room Number: ";
		String expectedInput="404";
		actualInput="404";
		

		setInOutStream();
		// get the actual input
		receivedInput=io.getReportingRoomNumber();
		
		getScreenResult();
		// test the screen number of line
        assertEquals(actualOutput.length, 1);
        // test the screen output
        assertEquals(expectedOutput, actualOutput[0]);
		// test the input
		assertEquals(expectedInput, receivedInput);
	
	}
	@Test
	public void testGetReportingRoomNumber_40_404() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Reporting Room Number: ";
		String expectedOutput2="Input the Reporting Room Number(3-4 characters): ";
		
		String expectedInput="404";
		actualInput="40 404";
		setInOutStream();
		// get the actual input
		receivedInput=io.getReportingRoomNumber();
		
		getScreenResult();

        assertEquals(actualOutput.length, 2); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
		assertEquals(expectedInput, receivedInput);
	
	}
	@Test
	public void testGetReportingRoomNumber_40444_12_404() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Reporting Room Number: ";
		String expectedOutput2="Input the Reporting Room Number(3-4 characters): ";
		String expectedOutput3="Input the Reporting Room Number(3-4 characters): ";
		
		String expectedInput="404";
		actualInput="40444 12 404";
		setInOutStream();
		// get the actual input
		receivedInput=io.getReportingRoomNumber();
		
		getScreenResult();

        assertEquals(actualOutput.length, 3); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
        assertEquals(expectedOutput3, actualOutput[2]);
		assertEquals(expectedInput, receivedInput);
	
	}
	
	
	
	
	
	@Test
	public void testGetAcademicYear_2012() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Academic Year: ";
		String expectedInput="2012";
		actualInput="2012";
			

		setInOutStream();
	
		receivedInput=io.getAcademicYear();
		
		getScreenResult();
	
		assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
		assertEquals(expectedInput, receivedInput);
	}
	@Test
	public void testGetAcademicYear_a2B3_2013() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Academic Year: ";
		String expectedOutput2="Input the Academic Year(4 digits): ";
		String expectedInput="2013";
		actualInput="a2B3 2013";
			

		setInOutStream();
	
		receivedInput=io.getAcademicYear();
		
		getScreenResult();
	
		assertEquals(actualOutput.length, 2); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
		assertEquals(expectedInput, receivedInput);
	}
	@Test
	public void testGetAcademicYear_10000_1992() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Academic Year: ";
		String expectedOutput2="Input the Academic Year(4 digits): ";
		String expectedInput="1992";
		actualInput="10000 1992";
			

		setInOutStream();
	
		receivedInput=io.getAcademicYear();
		
		getScreenResult();
	
		assertEquals(actualOutput.length, 2); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
		assertEquals(expectedInput, receivedInput);
	}
	@Test
	public void testGetAcademicYear_100_100_10000_1999() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Academic Year: ";
		String expectedOutput2="Input the Academic Year(4 digits): ";
		String expectedOutput3="Input the Academic Year(4 digits): ";
		String expectedOutput4="Input the Academic Year(4 digits): ";
		String expectedInput="1999";
		actualInput="100 100 10000 1999";
			

		setInOutStream();
	
		receivedInput=io.getAcademicYear();
		
		getScreenResult();
	
		assertEquals(actualOutput.length, 4); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
        assertEquals(expectedOutput3, actualOutput[2]);
        assertEquals(expectedOutput4, actualOutput[3]);
        
		assertEquals(expectedInput, receivedInput);
	}
	
	
	
	
	
	
	
	
	@Test
	public void testGetSemester_A() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Semester: ";
		String expectedInput="A";
		actualInput="A";
			

		setInOutStream();
	
		receivedInput=io.getSemester();
        
		getScreenResult();
		
		assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
		assertEquals(expectedInput, receivedInput);
	}
	public void testGetSemester_FirstTerm() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Semester: ";
		String expectedInput="First Term";
		actualInput="First Term";
			
		setInOutStream();
		
		receivedInput=io.getSemester();
        
		getScreenResult();
		
		assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
		assertEquals(expectedInput, receivedInput);
	}
	
	
	@Test
	public void testGet7RoomNumbers_402_403_405_406_407_408_411() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Room Numbers: ";
		ArrayList<String> expectedArrayList=new ArrayList<String>(Arrays.asList("402", "403", "405", "406", "407", "408", "411"));
		
		String actualInput="402 403 405 406 407 408 411";
			
		// set a test output
		ByteArrayOutputStream out = new ByteArrayOutputStream();
        System.setOut(new PrintStream(out));
     
 
        // set a test input
		InputStream  in = new ByteArrayInputStream(actualInput.getBytes());
		System.setIn(in);
		
		
		// get the actual input
		ArrayList<String> receivedArrayList=io.getRoomNumbers(7);
        
        
		// get the actual screen output
        out.flush();  
        String whatWasPrinted = new String(out.toByteArray());
        String[] linesOfOutput = whatWasPrinted.split(System.getProperty("line.separator"));  
        
        // test the screen number of line
        assertEquals(linesOfOutput.length, 1);
        
        // test the screen output
        assertEquals(expectedOutput, linesOfOutput[0]);
		
		// test the input
		assertEquals(true, expectedArrayList.equals(receivedArrayList));
	
	}
	@Test
	public void testGetStartTime_0830() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Starting Time: ";
		String expectedInput="0830";
		actualInput="0830";
			   
		setInOutStream();
		
		receivedInput=io.getStartingTime();
        
		getScreenResult();
	
		assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
		assertEquals(expectedInput, receivedInput);
	}
	@Test
	public void testGetStartTime_1530() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Starting Time: ";
		String expectedInput="1530";
		actualInput="1530";
		
		setInOutStream();
		
		receivedInput=io.getStartingTime();
        
		getScreenResult();	
		
		assertEquals(actualOutput.length, 1); 
        assertEquals(expectedOutput, actualOutput[0]);
		assertEquals(expectedInput, receivedInput);
	
	}
	@Test
	public void testGetStartTime_9999_0830() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Starting Time: ";
		String expectedOutput2="Input the Starting Time(0830-1530): ";
		String expectedInput="0830";
		actualInput="9999 0830";
			   
		setInOutStream();
		
		receivedInput=io.getStartingTime();
        
		getScreenResult();
	
		assertEquals(actualOutput.length, 2); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
		assertEquals(expectedInput, receivedInput);
	}
	@Test
	public void testGetStartTime_1531_0700_0900() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Starting Time: ";
		String expectedOutput2="Input the Starting Time(0830-1530): ";
		String expectedOutput3="Input the Starting Time(0830-1530): ";
		String expectedInput="0900";
		actualInput="1531 0700 0900";
			   
		setInOutStream();
		
		receivedInput=io.getStartingTime();
        
		getScreenResult();
	
		assertEquals(actualOutput.length, 3); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
        assertEquals(expectedOutput3, actualOutput[2]);
		assertEquals(expectedInput, receivedInput);
	}
	@Test
	public void testGetStartTime_0961_0975_930() throws IOException 
	{
		io= new IO();
		String expectedOutput="Input the Starting Time: ";
		String expectedOutput2="Input the Starting Time(0830-1530): ";
		String expectedOutput3="Input the Starting Time(0830-1530): ";
		String expectedInput="0900";
		actualInput="0961 0975 0930";
			   
		setInOutStream();
		
		receivedInput=io.getStartingTime();
        
		getScreenResult();
	
		assertEquals(actualOutput.length, 3); 
        assertEquals(expectedOutput, actualOutput[0]);
        assertEquals(expectedOutput2, actualOutput[1]);
        assertEquals(expectedOutput3, actualOutput[2]);
		assertEquals(expectedInput, receivedInput);
	}

}
